#include "http_generator.h"

#define GENERATOR_BUFFER_LEN	300

//appone la stringa 'c' alla stringa 'd'
#define generate_string(d, c)		strcat(d, c)
//appone il contenuto dell'header di tipo 'i' contenuto in 'e' alla stringa 'd'
#define generate_element(d, e, i)	generate_string(d, e[i])
#define generate_space(d)		generate_string(d, " ")
#define generate_CRLF(d)		generate_string(d, http_CRLF[HTTP_CRLF_TYPE])

void _generate_data(void *d, void *s, int l) {
	char *c = d; c+=strlen(d); memcpy((void*)c, (void*)s, l); c[l]='\0';
}

//appone alla stringa 's' gli header specificati da 'hs' e 'header_string'
void generate_headers(char *s, char hs[HTTP_MAX_HEADERS][HTTP_HEADER_LEN], char *header_string[], int header_len) {
	int i;
	for(i=0; i<http_rqst_header_len; i++) {
		if(hs[i][0]=='\0'){
			verbose2("header %d empty\n", i);
			continue;
		}
		generate_element(s, header_string, i);
		generate_string(s, http_header_delimiter[0]);
		generate_string(s, hs[i]);
		generate_CRLF(s);
	}
}

//genera la stringa di richiesta 'b' relativa al pacchetto request 'r'
void generate_request(http_req *r, char *b) {
	b[0] = '\0';
	
	generate_element(b, http_rqst_method_string, r->method);	generate_space(b);
	generate_element(b, network_rqst_method_string, r->uri); 	generate_space(b);
	generate_element(b, http_version, r->version);			generate_CRLF(b);
	generate_headers(b, r->headers, http_rqst_header_string, http_rqst_header_len);
	generate_CRLF(b);
	verbose1("generating data..");
	verbose2("len %d\n", find_content_len(r->headers, HTTP_MSG_TYPE_RQST));
	verbose1("generation complete\n");
}

//genera la stringa di risposta 'b' relativa al pacchetto response 'r'
void generate_response(http_resp *r, char *b) {
	b[0] = '\0';
	
	generate_element(b, http_version, r->version);			generate_space(b);
	generate_element(b, http_rspn_code_string, r->code);		generate_space(b);
	generate_element(b, http_rspn_reason_string, r->code);		generate_CRLF(b);
	generate_headers(b, r->headers, http_rspn_header_string, http_rspn_header_len);
	generate_CRLF(b);
}

//generano e trasmettono i pacchetti http e relativi payload
void send_http_req(int sock, http_req *r) {
	printf("sending->");printf_request(r);
	char buffer[GENERATOR_BUFFER_LEN];
	generate_request(r, buffer);
	nwrite(sock, buffer, strlen(buffer)*sizeof(char));
	if(r->data_len!=find_content_len(r->headers, HTTP_MSG_TYPE_RQST))
		printf("BAD DATA LEN\n");
	nwrite(sock, r->data, r->data_len);
}
void send_http_resp(int sock, http_resp *r) {
	printf("sending->");printf_response(r);
	char buffer[GENERATOR_BUFFER_LEN];
	generate_response(r, buffer);
	nwrite(sock, buffer, strlen(buffer)*sizeof(char));
	if(r->data_len!=find_content_len(r->headers, HTTP_MSG_TYPE_RSPN))
		printf("BAD DATA LEN\n");
	nwrite(sock, r->data, r->data_len);
}
